#include "tim7.h"
#include "lvgl.h"  // 为lvgl添加时基


uint32_t tim7_fac_ms = 168000;  // TIM6 毫秒因子
uint32_t tim7_fac_us = 168;     // TIM6 微秒因子
uint32_t lv_tick_ms = 1;       // lvgl使用的时基(默认1ms)


/**
 * 简述：初始化 TIM7
 * 参数：prescaler 预分频，取值范围：1 - 65536
 * 返回值：无
 **/
void tim7_init(uint32_t prescaler)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;

	// 使能 TIM7 时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
	

	TIM_TimeBaseInitStruct.TIM_Period        = 0; // 周期为 0 则定时器停止
	TIM_TimeBaseInitStruct.TIM_Prescaler     = prescaler - 1;
	TIM_TimeBaseInit(TIM7, &TIM_TimeBaseInitStruct);
    
	TIM_Cmd(TIM7, DISABLE);
	
	// 设置毫秒因子、微秒因子
	tim7_fac_ms = 168000 / prescaler;
	tim7_fac_us = 168 / prescaler;
	
	// 配置 NVIC
	NVIC_InitStruct.NVIC_IRQChannel                   = TIM7_IRQn;  // 通道号
	NVIC_InitStruct.NVIC_IRQChannelCmd                = ENABLE;  // TIM7中断总开关
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority        = 1;  // 响应优先级
	NVIC_Init(&NVIC_InitStruct);
}

/**
 * 简述：TIM7 毫秒延时，处理溢出情况
 * 参数：ms 要延时的毫秒数
 * 返回值：无
 **/
void tim7_delay_ms(uint32_t ms)
{
	// 计算以最大值计数的次数
	uint32_t count = tim7_fac_ms * ms / 0xFFFF;
	// 计算剩余值
	uint32_t remain = tim7_fac_ms * ms % 0xFFFF;
    
	if (count) {  // 溢出了
		TIM_SetAutoreload(TIM7, 0xFFFF);
		// 启动 TIM7
		TIM_Cmd(TIM7, ENABLE);
		while (count--) {
			// 等待更新标志;
			while (TIM_GetFlagStatus(TIM7, TIM_FLAG_Update) == RESET);
			TIM_ClearFlag(TIM7, TIM_FLAG_Update);
		}
		// 停止 TIM7
		TIM_Cmd(TIM7, DISABLE);
	}
	if (remain) {
		TIM_SetAutoreload(TIM7, remain);
		TIM_Cmd(TIM7, ENABLE);
		while (TIM_GetFlagStatus(TIM7, TIM_FLAG_Update) == RESET);
		TIM_ClearFlag(TIM7, TIM_FLAG_Update);
		TIM_Cmd(TIM7, DISABLE);
	}
}

/**
 * 简述：TIM7 毫秒延时，注意不能超 910us
 * 参数：us 要延时的微秒数
 * 返回值：无
 **/
void tim7_delay_us(uint32_t us)
{
	TIM_SetAutoreload(TIM7, us * tim7_fac_us);
	TIM_Cmd(TIM7, ENABLE);
	while (TIM_GetFlagStatus(TIM7, TIM_FLAG_Update) == RESET);
	TIM_ClearFlag(TIM7, TIM_FLAG_Update);
	TIM_Cmd(TIM7, DISABLE);
}

/**
 * 简述：启动 TIM7 毫秒定时，不处理溢出情况
 * 参数：ms 要定时的 ms 数
 * 返回值：无
 **/
void tim7_start_ms(uint32_t ms)
{
	// 设置 ARR (周期)
	TIM_SetAutoreload(TIM7, ms * tim7_fac_ms);
	// 使能 TIM7 更新中断
	TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
	// 使能定时器
	TIM_Cmd(TIM7, ENABLE);
}


/**
 * 简述：启动 TIM7 微秒定时，不处理溢出情况
 * 参数：us 要定时的 us 数
 * 返回值：无
 **/
void tim7_start_us(uint32_t us)
{
	// 设置 ARR (周期)
	TIM_SetAutoreload(TIM7, us * tim7_fac_us);
	// 使能 TIM7 更新中断
	TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
	// 使能定时器
	TIM_Cmd(TIM7, ENABLE);
}

/**
 * 简述：关闭 TIM7 定时器及中断
 * 参数：无
 * 返回值：无
 **/
void tim7_stop(void)
{
	// 禁用 TIM7 更新中断
	TIM_ITConfig(TIM7, TIM_IT_Update, DISABLE);
	// 禁用定时器
	TIM_Cmd(TIM7, DISABLE);
}


// lvgl的tick初始化函数
// presc: 时钟分频
// tick_ms: 计数溢出的时间，也就是LVGL的时基
void lvgl_tick_init(uint32_t presc,uint32_t tick_ms)
{
    tim7_init(presc);
    tim7_start_ms(tick_ms);
    lv_tick_ms = tick_ms;
}

// TIM7中断服务函数
void TIM7_IRQHandler(void)
{
    lv_tick_inc(lv_tick_ms);
	// 每隔5ms调用一次lv_timer_handler();
    TIM_ClearITPendingBit(TIM7,TIM_IT_Update); // 清中断标志
}
